Consider transitive fingerprints for freshness
Originally discovered through #1236, this commit fixes a bug in Cargo where
crates may not be recompiled when they need to (leading to obscure errors from
the compiler). The scenario in question looks like:
* Assume a dependency graph of `A -> B -> C` and `A -> C`
* Build all packages
* Modify C
* Rebuild, but hit Ctrl+C while B is building
* Modify A
* Rebuild again
Previously, Cargo only considered the freshness of a package to be the freshness
of the package itself (checking source files, for example). To handle transitive
recompilations, Cargo propagates a dirty bit throughout the dependency graph
automatically (instead if calculating it as such).
In the above example, however, we have a problem where as part of the last
rebuild Cargo thinks `B` and `C` are fresh! The artifact for `C` was just
recompiled, but `B`'s source code is untainted, so Cargo does not think that it
needs to recompile `B`. This is wrong, however, because one of `B`'s
dependencies was rebuilt, so it needs to be rebuilt.
To fix this problem, the fingerprint (a short hash) for all packages is now
transitively propagated (the fingerprint changes when an upstream package
changes). This should ensure that even when Ctrl+C is hit (or the situation
explained in #1236) that Cargo will still consider packages whose source code is
untainted as candidates for recompilation.
The implementation is somewhat tricky due to the actual fingerprint for a path
dependency not being known until *after* the crate is compiled (the fingerprint
is the mtime of the dep-info file).
Closes #1236